global crear_arbol_huffman
; void crear_arbol_huffman ( nodo_lista_t **l,  nodo_arbol_t **a)

extern lista_obtener_primero
extern lista_insertar_ordenado
extern malloc
extern printf
extern free
	
%define pp_lista ebp+8
%define p_nodo_arbol ebp+12 

%define offset_simbolo 0
%define offset_apariciones 1
%define offset_valido 5
%define offset_p_padre	9 
%define offset_p_izq	13
%define offset_p_der	17
%define null 0
%define offset_p_arbol 0
%define offset_siguiente 4

%define sizeof_nodo_arbol_t 21
%define invalido 0
	
section .data
ptr_primero:	dd 	0
msg_error_lista_vacia:	db	'ERROR: Lista Vacia',10,0 
msg_error_overflow:	db	'ERROR: La suma de apariciones no entra en 32 bits',10,0
	

	
section .text
	
crear_arbol_huffman:	
	;enter 0,0	comentado para probar con valgrind
	push ebp
	mov ebp,esp
	
	push ebx
	push esi
	push edi

	mov ebx, [pp_lista]
	cmp dword [ebx],null   	; ebx guarda el puntero a la lista (es simple, no doble **)
	jne _ciclo

_lista_vacia:
	; Aqui no hay memoria que liberar.
	push msg_error_lista_vacia
	call printf
	add esp,4
	jmp fin
	
	
_ciclo:	
	push dword ptr_primero
	push dword [pp_lista]
	call lista_obtener_primero
	add esp,8

	mov esi, [ptr_primero]	; esi guarda el puntero al primer elemento de la lista
	
	cmp dword [ebx], null
	je _solo_queda_un_arbol

	push dword ptr_primero
	push dword [pp_lista]
	call lista_obtener_primero
	add esp,8

	mov edi, [ptr_primero] 	; edi guarda el puntero al segundo elemento de la lista

	push dword sizeof_nodo_arbol_t
	call malloc
	add esp,4		; en eax tengo el nuevo nodo pedido.

	mov dword [eax + offset_valido], invalido ; el nuevo nodo no tiene simbolo
	mov dword [eax + offset_p_padre], null
	
	mov ecx, [esi+offset_p_arbol]
	mov [eax + offset_p_izq], ecx ; primer elemento de la lista a la izq.
	mov [ecx + offset_p_padre], eax  ; hijo izquierda conoce al padre
	mov edx, [ecx + offset_apariciones]
	
	mov ecx, [edi+offset_p_arbol]
	mov [eax + offset_p_der], ecx ; segundo elemento de la lista a la der.
	mov [ecx + offset_p_padre], eax  ; hijo derecho conoce al padre
	
	add edx, [ecx + offset_apariciones]
	
	jc _overflow
	mov [eax + offset_apariciones],edx ; seteamos la suma de las apariciones

	; Reaprovechamos uno de los dos nodos de lista y el otro lo borramos
	mov [esi+offset_p_arbol],eax
	
	push edi
	call free
	add esp,4
	
	push esi     		; pasamos ptr al nuevo nodo
	push ebx		; pasamos el ptr doble a la lista
	call lista_insertar_ordenado
	add esp,8

	jmp _ciclo

	
_solo_queda_un_arbol:
	mov eax, [esi+offset_p_arbol]
	mov edi, [p_nodo_arbol]
	mov [edi], eax		; usamos el ptr p_nodo_arbol para escribir el resultado
	
	push esi
	call free		; Eliminamos el ultimo nodo que ya no se usa
	add esp,4		; Si no hacemos esto tendriamos un memory leak
	
	; Para informar que ya se destruyo la lista y no perder memoria
	mov edi, [pp_lista]
	mov dword [edi], null	
	
	jmp fin
	
	
_overflow:
	; Liberamos la memoria de los elementos que sacamos de lista.
	push eax
	call free		; liberamos el nodo que creamos para unir los arboles
	add esp,4

	push esi
	call free		; liberamos el primero que sacamos
	add esp,4

	push edi
	call free		; liberamos el segundo que sacamos
	add esp,4

	push msg_error_overflow
	call printf
	add esp,4

fin:
	pop edi
	pop esi
	pop ebx
	leave
	ret
	








